#include "usintl_kbdec.h"
#include <ustdio.h>
#include <stdio.h>
kbdmsg_t buffer[KBD_BUFSIZE];
int rawkbd_file = 0;
int ptyv_file = 0;
extern int errno;
unsigned char kbdus_reg[128] =
{
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
  '9', '0', '-', '=', '\b',	/* Backspace */
  '\t',			/* Tab */
  'q', 'w', 'e', 'r',	/* 19 */
  't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',	/* Enter key */
    0,			/* 29   - Control */
  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',	/* 39 */
 '\'', '`',   0,		/* Left shift */
 '\\', 'z', 'x', 'c', 'v', 'b', 'n',			/* 49 */
  'm', ',', '.', '/',   0,				/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */
};		
unsigned char kbdus_caps[128] =
{
    0,  27, '1', '2', '3', '4', '5', '6', '7', '8',	/* 9 */
  '9', '0', '-', '=', '\b',	/* Backspace */
  '\t',			/* Tab */
  'Q', 'W', 'E', 'R',	/* 19 */
  'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\n',	/* Enter key */
    0,			/* 29   - Control */
  'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';',	/* 39 */
 '\'', '`',   0,		/* Left shift */
 '\\', 'Z', 'X', 'C', 'V', 'B', 'N',			/* 49 */
  'M', ',', '.', '/',   0,				/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */
};		
unsigned char kbdus_shift[128] =
{
	0,  27, '!', '@', '#', '$', '%', '^', '&', '*',	/* 9 */
  '(', ')', '_', '+', '\b',	/* Backspace */
  '\t',			/* Tab */
  'Q', 'W', 'E', 'R',	/* 19 */
  'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',	/* Enter key */
    0,			/* 29   - Control */
	'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',	/* 39 */
 '\"', '~',   0,		/* Left shift */
 '|', 'Z', 'X', 'C', 'V', 'B', 'N',			/* 49 */
  'M', '<', '>', '?',   0,				/* Right shift */
  '*',
    0,	/* Alt */
  ' ',	/* Space bar */
    0,	/* Caps lock */
    0,	/* 59 - F1 key ... > */
    0,   0,   0,   0,   0,   0,   0,   0,
    0,	/* < ... F10 */
    0,	/* 69 - Num lock*/
    0,	/* Scroll Lock */
    0,	/* Home key */
    0,	/* Up Arrow */
    0,	/* Page Up */
  '-',
    0,	/* Left Arrow */
    0,
    0,	/* Right Arrow */
  '+',
    0,	/* 79 - End key*/
    0,	/* Down Arrow */
    0,	/* Page Down */
    0,	/* Insert Key */
    0,	/* Delete Key */
    0,   0,   0,
    0,	/* F11 Key */
    0,	/* F12 Key */
    0,	/* All other keys are undefined */
};	

char decode_keystroke(uint8_t scancode,uint8_t modifier){
	char result;
	if (modifier & KBD_CPSLCK_BIT){
		result = kbdus_caps[scancode];
	} else if (modifier & KBD_SHIFT_BIT){
		result = kbdus_shift[scancode];
	} else {
		result = kbdus_reg[scancode];
	}
	return result;
}

void process_keystrokes(){
	printf("usintl_kbdec: reading from /dev/rawkbd\n");
	int read = uread(rawkbd_file,(uint8_t *)buffer,sizeof(kbdmsg_t)*KBD_BUFSIZE);
	if (read == -1){
		printf("usintl_kbdec: error reading from /dev/rawkbd\n");
		return;
	}
	if (read == 0){
		printf("usintl_kbdec: process_keystrokes called with empty buffer\n");
		return;
	}
	for (int cur_idx = 0;cur_idx < (read/3);cur_idx++){
		kbdmsg_t keystroke = buffer[cur_idx];
		char ascii = decode_keystroke(keystroke.scancode,keystroke.modifiers);
		if (ascii == 0)
			continue;// Special character
		switch (keystroke.msg_type){
			case KBD_MSG_TYPE:
			case KBD_MSG_PRESS:
				uwrite(ptyv_file,(uint8_t *)&ascii,1);
				break;
			case KBD_MSG_RELEASE:
				continue;
		}
	}
}

int initialize_decoder(){
	rawkbd_file = uopen("/dev/rawkbd",0x4000,0);
	if (rawkbd_file == -1){
		printf("FAILED(\"/dev/rawkbd\",%x)\n",errno);
		return -1;
	}
	ptyv_file = uopen("/dev/ptyv",0x4001,0);
	if (ptyv_file == -1){
		printf("FAILED(\"/dev/ptyv\",%x)\n",errno);
		return -1;
	}
	return 0;

}